#!/bin/bash

# Define Paths
AWSHOME='/root/.aws'
COLXML='/etc/columnstore/Columnstore.xml'
IFLAG='/etc/columnstore/container-initialized'
LOG_PREFIX='/var/log/mariadb/columnstore'
MCS_INSTALL_BIN='/usr/bin'
JEMALLOC_PATH='/usr/lib64/libjemalloc.so.2'

export LD_PRELOAD=$JEMALLOC_PATH

# Set StorageManager Defaults If Missing
USE_S3_STORAGE="${USE_S3_STORAGE:-false}"

# Miscellaneous Variables
CMAPI_PID=$(pgrep -f cmapi_server)
PROGS=('StorageManager' 'load_brm' 'workernode' 'controllernode' 'PrimProc' 'DMLProc' 'DDLProc' 'WriteEngineServer')
RET=$'\n'
SERVER_ID=$(hostname -i | cut -d "." -f 4)

# Set Credential Defaults If Missing
CMAPI_KEY="${CMAPI_KEY:-somekey123}"
CEJ_USER="${CEJ_USER:-cej}"
CEJ_PASS="${CEJ_PASS:-C0lumnStore!}"
MAX_USER="${MAX_USER:-maxscale}"
MAX_PASS="${MAX_PASS:-C0lumnStore!}"
MAX_HOST="${MAX_HOST:-%}"
PM1="${PM1:-127.0.0.1}"
REP_USER="${REP_USER:-idbrep}"
REP_PASS="${REP_PASS:-C0lumnStore!}"
REP_HOST="${REP_HOST:-%}"

echo "[Beginning initialization]"

# Adjust Columnstore Cluster Configuration
if [[ $CLUSTER == true ]]; then
    cat <<EOT >> /etc/my.cnf.d/columnstore.cnf
$RET
server_id = $SERVER_ID
collation_server = utf8_general_ci
character_set_server = utf8
log_bin = /var/lib/mysql/mariadb-bin
log_bin_index = /var/lib/mysql/mariadb-bin.index
relay_log = /var/lib/mysql/mariadb-relay
relay_log_index = /var/lib/mysql/mariadb-relay.index
log_slave_updates = ON
gtid_strict_mode = ON
innodb_strict_mode = OFF
log_error = /var/log/mariadb/columnstore/mariadb-error.log
columnstore_compression_type = LZ4
columnstore_use_import_for_batchinsert=ALWAYS$RET
EOT
else
    cat <<EOT >> /etc/my.cnf.d/columnstore.cnf
$RET
server_id = $SERVER_ID
collation_server = utf8_general_ci
character_set_server = utf8
log_slave_updates = ON
gtid_strict_mode = ON
innodb_strict_mode = OFF
log_error = /var/log/mariadb/columnstore/mariadb-error.log
columnstore_compression_type = LZ4
columnstore_use_import_for_batchinsert=ALWAYS$RET
EOT
fi

# Add API Key To 'cmapi_server.conf'
sed -i "s@^x-api-key.*@x-api-key = '${CMAPI_KEY//&/\\&}'@" /etc/columnstore/cmapi_server.conf

# Storagemanager Configuration
if [ $USE_S3_STORAGE = true ]; then
    xmlstarlet ed -L -u '/Columnstore/Installation/DBRootStorageType' -v "StorageManager" $COLXML
    xmlstarlet ed -L -u '/Columnstore/StorageManager/Enabled' -v "Y" $COLXML
    xmlstarlet ed -L -u '/Columnstore/SystemConfig/DataFilePlugin' -v "libcloudio.so" $COLXML
    sed -i "s|cache_size = 2g|cache_size = 4g|" /etc/columnstore/storagemanager.cnf
    sed -i "s|^service =.*|service = S3|" /etc/columnstore/storagemanager.cnf
    sed -i "s|^region =.*|region = $S3_REGION|" /etc/columnstore/storagemanager.cnf
    sed -i "s|^bucket =.*|bucket = $S3_BUCKET|" /etc/columnstore/storagemanager.cnf
    sed -i "s|^# endpoint =.*|endpoint = $S3_ENDPOINT|" /etc/columnstore/storagemanager.cnf
    sed -i "s|^# aws_access_key_id =.*|aws_access_key_id = $S3_ACCESS_KEY_ID|" /etc/columnstore/storagemanager.cnf
    sed -i "s|^# aws_secret_access_key =.*|aws_secret_access_key = $S3_SECRET_ACCESS_KEY|" /etc/columnstore/storagemanager.cnf
fi

# Add AWS CLI Credentials
if [[ $USE_AWS_CLI == true ]]; then
    mkdir $AWSHOME
    cat <<EOT >> $AWSHOME/credentials
$RET
[default]
aws_access_key_id = $S3_ACCESS_KEY_ID
aws_secret_access_key = $S3_SECRET_ACCESS_KEY$RET
EOT
fi

# Verify All Programs Are Available
for i in "${PROGS[@]}" ; do
    if [ ! -x $MCS_INSTALL_BIN/$i ] ; then
        echo "$i doesn't exist."
        exit 1
    fi
done

# Conditional Provisioning
if [[ $(hostname -s) == "$PM1" ]] || [[ $CLUSTER == false ]]; then

    # Start Primary Node
    echo 'Starting Columnstore processes...'

    echo 'Starting StorageManager'
    touch $LOG_PREFIX/storagemanager.log && chmod 666 $LOG_PREFIX/storagemanager.log
    $MCS_INSTALL_BIN/StorageManager &> $LOG_PREFIX/storagemanager.log &
    echo "StorageManager PID = $!"

    sleep 1

    echo 'Loading BRM'
    $MCS_INSTALL_BIN/mcs-loadbrm.py no > /dev/null 2>&1

    echo 'Starting workernode'
    touch $LOG_PREFIX/workernode.log && chmod 666 $LOG_PREFIX/workernode.log
    $MCS_INSTALL_BIN/workernode DBRM_Worker1 &> $LOG_PREFIX/workernode.log &
    echo "workernode PID = $!"

    echo 'Starting controllernode'
    touch $LOG_PREFIX/controllernode.log && chmod 666 $LOG_PREFIX/controllernode.log
    $MCS_INSTALL_BIN/controllernode &> $LOG_PREFIX/controllernode.log &
    echo "controllernode PID = $!"

    sleep 2

    echo 'Starting PrimProc'
    touch $LOG_PREFIX/primproc.log && chmod 666 $LOG_PREFIX/primproc.log
    $MCS_INSTALL_BIN/PrimProc &> $LOG_PREFIX/primproc.log &
    echo "PrimProc PID = $!"

    sleep 1

    echo 'Starting WriteEngineServer'
    touch $LOG_PREFIX/writeengineserver.log && chmod 666 $LOG_PREFIX/writeengineserver.log
    $MCS_INSTALL_BIN/WriteEngineServer &> $LOG_PREFIX/writeengineserver.log &
    echo "WriteEngineServer PID = $!"

    sleep 2

    echo 'Starting DMLProc'
    touch $LOG_PREFIX/dmlproc.log && chmod 666 $LOG_PREFIX/dmlproc.log
    $MCS_INSTALL_BIN/DMLProc &> $LOG_PREFIX/dmlproc.log &
    echo "DMLProc PID = $!"

    echo 'Starting DDLProc'
    touch $LOG_PREFIX/ddlproc.log && chmod 666 $LOG_PREFIX/ddlproc.log
    $MCS_INSTALL_BIN/DDLProc &> $LOG_PREFIX/ddlproc.log &
    echo "DDLProc PID = $!"

    echo 'Running dbbuilder'
    $MCS_INSTALL_BIN/dbbuilder 7 &> $LOG_PREFIX/dbbuilder.log

    echo 'Starting MariaDB server...'

    /etc/init.d/mariadb start

    MARIADB_RUNNING=$(mariadb-admin ping)
    if [[ $MARIADB_RUNNING == *"alive"* ]]; then
        # Load Time Zone Data
        mysql_tzinfo_to_sql /usr/share/zoneinfo | mariadb mysql

        # Set Up Cross Engine Join User
        mariadb -e "
            GRANT SELECT, PROCESS
            ON *.* TO '$CEJ_USER'@'127.0.0.1'
            IDENTIFIED BY '$CEJ_PASS';
            ALTER USER '$CEJ_USER'@'127.0.0.1' PASSWORD EXPIRE NEVER;
        "
        if [ $? -ne 0 ]; then
            echo 'ERROR: During cross engine join user creation.'
            exit 1
        fi
        xmlstarlet ed -L -u '/Columnstore/CrossEngineSupport/User' -v "$CEJ_USER" $COLXML
        xmlstarlet ed -L -u '/Columnstore/CrossEngineSupport/Password' -v "$CEJ_PASS" $COLXML
        xmlstarlet ed -L -u '/Columnstore/CrossEngineSupport/host' -v "127.0.0.1" $COLXML
        echo 'Cross engine join user created'

        # Set Up Admin User
        if [ ! -z $ADMIN_USER ] && [ ! -z $ADMIN_PASS ]; then
            mariadb -e "
                GRANT ALL PRIVILEGES
                ON *.* TO '$ADMIN_USER'@'$ADMIN_HOST'
                IDENTIFIED BY '$ADMIN_PASS'
                WITH GRANT OPTION;
                ALTER USER '$ADMIN_USER'@'$ADMIN_HOST' PASSWORD EXPIRE NEVER;
            "
            if [ $? -ne 0 ]; then
                echo "ERROR: During replication user creation."
                exit 1
            fi
            echo 'Administration user created'
        fi

        # Set Up Replication User
        mariadb -e "
            GRANT REPLICATION SLAVE ADMIN,
            REPLICATION SLAVE,
            BINLOG MONITOR,
            SLAVE MONITOR,
            REPLICATION MASTER ADMIN
            ON *.* TO '$REP_USER'@'$REP_HOST'
            IDENTIFIED BY '$REP_PASS';
            ALTER USER '$REP_USER'@'$REP_HOST' PASSWORD EXPIRE NEVER;
        "
        if [ $? -ne 0 ]; then
            echo "ERROR: During replication user creation."
            exit 1
        fi
        echo 'Replication user created'

        # Set Up MaxScale User
        mariadb -e "
            GRANT BINLOG ADMIN,
            READ_ONLY ADMIN,
            RELOAD,
            BINLOG MONITOR,
            SLAVE MONITOR,
            REPLICATION MASTER ADMIN,
            REPLICATION SLAVE ADMIN,
            REPLICATION SLAVE,
            SHOW DATABASES
            ON *.* TO '$MAX_USER'@'$MAX_HOST' IDENTIFIED BY '$MAX_PASS';
            ALTER USER '$MAX_USER'@'$MAX_HOST' PASSWORD EXPIRE NEVER;
        "
        if [ $? -ne 0 ]; then
            echo "ERROR: Creating user '$MAX_USER'@'$MAX_HOST'."
            exit 1
        fi
        mariadb -e "
            GRANT SELECT ON mysql.columns_priv TO '$MAX_USER'@'$MAX_HOST';
            GRANT SELECT ON mysql.db TO '$MAX_USER'@'$MAX_HOST';
            GRANT SELECT ON mysql.procs_priv TO '$MAX_USER'@'$MAX_HOST';
            GRANT SELECT ON mysql.proxies_priv TO '$MAX_USER'@'$MAX_HOST';
            GRANT SELECT ON mysql.roles_mapping TO '$MAX_USER'@'$MAX_HOST';
            GRANT SELECT ON mysql.tables_priv TO '$MAX_USER'@'$MAX_HOST';
            GRANT SELECT ON mysql.user TO '$MAX_USER'@'$MAX_HOST';
        "
        if [ $? -ne 0 ]; then
            echo "ERROR: Granting SELECT to '$MAX_USER'@'$MAX_HOST'."
            exit 1
        fi
        echo 'MaxScale user created'

        # Securing MariaDB Installation
        mariadb -e "
            DROP DATABASE IF EXISTS test;
            DELETE FROM mysql.user WHERE User='';
        "
        if [ $? -ne 0 ]; then
            echo 'ERROR: Securing MariaDB'
            exit 1
        fi
    fi

    # Stop Primary Node

    echo 'Stopping MariaDB server...'

    /etc/init.d/mariadb stop

    echo 'Saving BRM'
    if [ ! -z "$(pidof "${PROGS[@]}")" ]; then
        $MCS_INSTALL_BIN/mcs-savebrm.py
    fi

    echo 'Stopping Columnstore processes...'
    for i in "${PROGS[@]}"; do
        if [ ! -z "$(pidof $i)" ]; then
            echo "Sending SIGTERM to $i"
            pkill -15 $i > /dev/null
            sleep 3
            counter=1
            while [[ -n $(pidof StorageManager) ]] && [[ $counter -le 60 ]]
            do
                sleep 1
                ((counter++))
            done
        fi
    done
    for i in "${PROGS[@]}"; do
        if [ ! -z "$(pidof $i)" ]; then
            echo "Sending SIGKILL to $i"
            pkill -9 $i > /dev/null
            sleep 3
            counter=1
            while [[ -n $(pidof StorageManager) ]] && [[ $counter -le 60 ]]
            do
                sleep 1
                ((counter++))
            done
        fi
    done

    echo 'Clearing shared memory...'
    $MCS_INSTALL_BIN/clearShm

    echo 'Stopping CMAPI...'

    if [[ ! -z $CMAPI_PID ]]; then
        kill $CMAPI_PID > /dev/null
    fi

else

    # Start Replicas
    echo 'Starting replicas...'

    /etc/init.d/mariadb start

    # Configure Replication On Slaves
    echo 'Setting up replication...'

    $MCS_INSTALL_BIN/mariadb -e "
        STOP SLAVE;
        CHANGE MASTER TO MASTER_HOST='$PM1',
        MASTER_USER='$REP_USER',
        MASTER_PASSWORD='$REP_PASS',
        MASTER_USE_GTID=slave_pos,
        MASTER_CONNECT_RETRY=10;
        START SLAVE;
    "
    if [ $? -ne 0 ]; then
        echo 'ERROR: Performing CHANGE MASTER on replica'
        exit 1
    fi

    # Stop Replicas
    echo 'Stopping replicas...'

    /etc/init.d/mariadb stop

fi

# Clean Remnants
rm -f /var/lib/mysql/*.err

# Standardize Logging Ownership
chown -R root:mysql /var/log/mariadb
find /var/log/mariadb/ -type d -exec chmod g+ws {} \;

# Mark Container Initialized
touch $IFLAG

# Return To cmapi-start
echo "[Initialization complete]$RET"
exit 0
